#include "Test.Application.h"

#undef  APP_NAME
#define APP_NAME	TestBoxPhysics
#undef  APP_BASE
#define APP_BASE	TestPhysicsApp


class APP_NAME : public APP_BASE
{
protected:
	PhysicsWorld	world;

	PhysicsObject	obj1;
	PhysicsObject	obj2;
	PhysicsObject	plane;

	const vec2		obj1Size;
	const vec2		obj2Size;
	const vec2		planeSize;
	
	BatchMaterial	material;

public:
	APP_NAME (IPlatform *platform, EDevice::type deviceType) :
		APP_BASE( platform, deviceType ),
		obj1Size(0.1f), obj2Size(0.1f), planeSize(2.0f, 0.05f) 
	{}
	

	void Update (float dt) override
	{
		APP_BASE::Update( dt );
		
		ESS()->GetGraphicsEngine()->GetViewport()->Apply();
		ESS()->GetGLStateManager()->ClearColor( color4f( 0.0f ) );


		// process physics
		world.Update( dt );
		
		Draw();

		batch.Flush();
		batch.Clear();
		
		ESS()->GetGraphicsEngine()->SwapBuffers();
	}


	void Draw ()
	{
		ESS()->GetGraphicsEngine()->GetRender2D().DrawRect( material, plane.GetPosition(),
			planeSize * 2.0f, color4u::Default::Blue(), false, false );
		
		ESS()->GetGraphicsEngine()->GetRender2D().DrawRect( material, obj1.GetPosition(),
			obj1Size * 2.0f, color4u::Default::Red(), false, false );

		ESS()->GetGraphicsEngine()->GetRender2D().DrawRect( material, obj2.GetPosition(),
			obj2Size * 2.0f, color4u::Default::Green(), false, false );
	}


	void OnEnter () override
	{
		ProgramPtr		program = ESS()->GetGraphicsEngine()->GetShaderManager()->
								GetDefaultProgram( EDefaultShader::COLORED );

		material.SetProgram( program );


		world.Create();
		world.SetGravity( vec2(0.0f, -1.0f) );
		
		b2BodyDef bodydef;

		bodydef.type = b2_dynamicBody;
		obj1.Create( world.GetWorld(), bodydef );
		obj1.SetMass( 1.0f );
		obj1.SetTransform( vec2(0.2f, 1.0f), 0.0f );
		ShapeUtils::AddBox( obj1, obj1Size );

		bodydef.type = b2_dynamicBody;
		obj2.Create( world.GetWorld(), bodydef );
		obj2.SetMass( 2.0f );
		obj2.SetTransform( vec2(0.0f, 0.25f), 0.0f );
		ShapeUtils::AddBox( obj2, obj2Size );

		bodydef.type = b2_staticBody;
		plane.Create( world.GetWorld(), bodydef );
		plane.SetTransform( vec2(0.0f, -0.8f), 0.0f );
		ShapeUtils::AddBox( plane, planeSize );
	}
};